package aor2.cpu;

import aor2.common.Tracker;
import aor2.components.Element;
import aor2.components.Restorable;
import aor2.components.records.RecordInternBus;

/**
 * kada se radi restore za komponente koje imaju history, mora da se prvo uradi
 * restore za CPUclock! i u implementaciji restora prvo ceo history obrisati, pa
 * tek onda restaurirati stanja...
 * 
 * @author Moxi
 * 
 */
public enum InternBus implements Element, Restorable {

	M1(UNDEFINED), M2(UNDEFINED);

	long state;
	
	private boolean highZ = false;
	public boolean isHighZ() {
		return highZ;
	}

	private Tracker history;

	public long getState() {
		return state;
	}

	public Tracker getHistory() {
		return history;
	}

	@Override
	public void setState(long state) {
		highZ = false;
		if (this.state != state) {
			history.put(new RecordInternBus(this));
			this.state = state;
		}
		this.state = state;
	}

	private InternBus(long state) {

		this.state = state;
		history = new Tracker();
		history.put(new RecordInternBus(this));
		highZ = true;
	}

	private void clr() {
		setState(UNDEFINED);
		highZ = true;
	}

	public static void clear() {
		M1.clr();
		M2.clr();
	}

	public static String info() {
		return "M1[" + M1.getState() + "] M2[" + M2.getState() + "]";
	}

	@Override
	public void restore(String restorePoint) {
		String trim = restorePoint.replace(beginTag(), "");
		trim = trim.replace(endTag(), "");
		trim = trim.trim();
		String[] states = trim.split(" ");
		M1.history = new Tracker();
		M2.history = new Tracker();
		M1.setState(Long.parseLong(states[0]));
		M2.setState(Long.parseLong(states[1]));
	}

	@Override
	public String createRestorePoint() {
		return beginTag() + "\n\t" + M1.getState() + " " + M2.getState() + "\n"
				+ endTag();
	}

	@Override
	public String beginTag() {
		return "<InternBus>";
	}

	@Override
	public String endTag() {
		return "</InternBus>";
	}

	public void previousClk() {
		RecordInternBus tmp = (RecordInternBus) history.getFromTop(0);
		if (tmp != null) {
			while (((ClockCPU) (tmp).getMark()).compareTo(ClockCPU
					.getInstance()) > 0 && tmp != null) {
				history.takeFromTop();
				tmp = (RecordInternBus) history.getFromTop(0);
			}
			if (tmp != null)
				//setState(((RecordInternBus) history.takeFromTop()).getValue());
				state = tmp.getValue();
		}
	}

	public static void main(String[] args) {
		String restString = InternBus.M1.createRestorePoint();

		System.out.println(restString);

		InternBus.M1.setState(1000);
		InternBus.M2.setState(200);

		String preString = restString;
		restString = InternBus.M1.createRestorePoint();

		System.out.println(restString);

		InternBus.M2.restore(preString);
		restString = InternBus.M1.createRestorePoint();

		System.out.println(restString);
	}
}
